#include <iostream>

/*
菱形继承问题

1. 菱形继承问题的关键在于，找到在同一个派生类中存在多个来自同一个基类的成员，这个基类就是虚基类，所有继承自这个虚基类
的派生类 都需要明确指定 虚继承这个虚基类！！！

2. 指定了虚继承虚基类的情况下，虚基类要么有默认构造，要么在派生类中的初始化列表中明确构造虚基类

3. 虚基类的成员在派生类中仅会存在一份数据，即使是菱形继承也只存在一份。
其实现原理是，派生类中有一个vbptr（虚基类指针），这个vbptr指向vbtable（虚基类表），这张表中存放着这个
vbptr到派生类对象的内存起始地址的偏移量，以及由这个vbptr到这个派生类中继承下来的虚基类成员的偏移量。

*/

class A {
public:
    A(int a) : _a(a) {
        std::cout << "A::A(int)" << std::endl;
    }

    ~A() {
        std::cout << "A::~A()" << std::endl;
    }

protected:
    int _a;
};

class B : virtual public A {
public:
    B(int a, int b) : A(a), _b(b) {
        std::cout << "B::B(int,int)" << std::endl;
    }

    ~B() {
        std::cout << "B::~B()" << std::endl;
    }

protected:
    int _b;
};

class C : virtual public A {
public:
    C(int a, int c) : A(a), _c(c) {
        std::cout << "C::C(int,int)" << std::endl;
    }

    ~C() {
        std::cout << "C::~C()" << std::endl;
    }

protected:
    int _c;
};

class D : public B, public C {
public:
    D(int a, int b, int c, int d) : A(a), B(a, b), C(a, c), _d(d) {
        std::cout << "D::D(int,int,int,int)" << std::endl;
    }
    ~D() {
        std::cout << "D::~D()" << std::endl;
    }

protected:
    int _d;
};
int main() {
    D d(1, 2, 3, 4);
    return 0;
}